<?php
namespace App\Admin\Actions;


use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;


/**
 * Admin通用CRUD 通用查询
 */
trait DataTable
{
	
	public function index(Request $request, ActionSetter $setter)
	{
		$this->initDataTableAction();

		// 默认配置器与自定义配置器
		$this->setDefaultSetter($setter);
		if( method_exists($this, 'dataTable') ){
			$this->dataTable($setter);
		}

		// 验证器
		$validated = $this->getValidated($setter, $request);

		$query = $this->modelName()::query();

		// 软删除
		if( $request->has('trashed') ){
			$query->onlyTrashed();
		}


		// 搜索与排序查询条件
		$setter->call('search', $query, $validated);
		$setter->call('sort', $query, $validated);

        // 分页查询出结果
        list($page, $page_size) = $this->getPaginateArgs($request);
		$models = $setter->call('select', $query, $page, $page_size);

        // 分页后的数据再处理
		$after = $setter->call('after', $models);
		$data = ($after===null) ? $models : $after;

		return [
			'code' => 0,
			'message' => 'success',
			'data' => $data
		];
	}

	private function initDataTableAction()
	{
		$class_name = class_basename($this);

		abort_unless(method_exists($this, 'modelName'), 500, "{$class_name} 未设置 modelName() 方法");
	}

	/**
	 * 获得结果验证的数据
	 */
	private function getValidated($setter, $request)
	{
		if( $setter->has('validate') ){
			return $setter->call('validate', $request);;
		}

		if( !$setter->has('validator') ){
			return [];
		}

		$validator = $setter->call('validator', $request);

		if(!($validator instanceof \Illuminate\Validation\Validator)){
			abort(500, 'updateActionValidator返回的不是验证器');
		}

        if ($validator->fails()) {
            throw new ValidationException($validator);
        }

        return $validator->validated();
	}

	/**
	 * 获得分页参数
	 */
	private function getPaginateArgs($request):array
	{
    	$validator = Validator::make($request->all(), [
			'page'      => 'sometimes|integer|min:1',
			'page_size' => 'sometimes|integer|between:1,100',
			'trashed'   => 'sometimes|accepted',
    	]);

        if ($validator->fails()) {
            throw new ValidationException($validator);
        }

        return [
        	(int) Arr::get($validator->validated(), 'page', 1),
        	(int) Arr::get($validator->validated(), 'page_size', 10),
        ];
	}

	/**
	 * 设置默认设置器
	 * 可用配置
	 *     - 验证配置器 validate|validator 二选一
	 *     - 搜索配置器 search
	 *     - 排序配置器 sort
	 *     - 查询配置器 select
	 *     - 处理配置器 then
	 */
	private function setDefaultSetter($setter)
	{
		// 默认排序器 主键倒序
		$setter->sort(function($query, $validated){
			$query->latest();
		});

		// 默认查询器 分页查询
		$setter->select(function($query, $page, $page_size){
			// Illuminate\Pagination\LengthAwarePaginator
			return $query->paginate($page_size, '*', 'page', $page);
		});
	}
}

